using System.Net;
using System.Text.Json.Nodes;
using HeyRed.Mime;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Models;
using Utils;

namespace Controllers;

[ApiController]
[Route("api/[controller]")]
public class OnlyOfficeController(IWebHostEnvironment webHostEnvironment, SQLiteDbContext dbCtx) : ControllerBase {
  private readonly IWebHostEnvironment _webHostEnvironment = webHostEnvironment;
  private readonly SQLiteDbContext _dbCtx = dbCtx;

  private readonly string UPLOADS = "uploads";

  [HttpGet("Index")]
  public IActionResult Index() {
    return Ok(new {
      Success = true,
      Status = 200,
      Message = "OK",
      Data = DateTime.UtcNow,
    });
  }


  [HttpPost("Uploads")]
  public async Task<IActionResult> UploadsAsync(IFormFile file) {
    var path = Path.Combine(_webHostEnvironment.ContentRootPath, UPLOADS);
    using var stream = new MemoryStream();
    await file.CopyToAsync(stream);
    string sha256 = SHA256Helper.Parse(stream);

    string originFileName = file.FileName;
    string fileExt = Path.GetExtension(file.FileName); // 带有前缀点
    string fileDir = Path.Combine(path, sha256[..2]);
    // string fileFullName = Path.Combine(fileDir, $"{ sha256[2..] }{ fileExt }");

    // 保存文件    
    await SaveFileHelper.SaveFileAsync($"{ sha256[2..] }{ fileExt }", fileDir, stream);

    var now = DateTime.UtcNow;
    // 需要写入数据库
    var _file = new FileData {
      FileExt = fileExt,
      FileFullSha256 = sha256,
      OriginFileName = originFileName,

      CreatedAt = now,
      UpdatedAt = now,
    };

    await _dbCtx.FileDatas.AddAsync(_file);

    await _dbCtx.SaveChangesAsync();


    return Ok();
  }



  [HttpGet("Files")]
  public async Task<IActionResult> GetAllFilesAsync() {
    var files = await _dbCtx.FileDatas.ToListAsync();

    return Ok(new ResponseOk<List<FileData>> {
      Data = files
    });
  }


  [HttpGet("File/{id:long}")]
  public async Task<IActionResult> GetFileAsync(long id) {
    System.Console.WriteLine($"获取文件流: 文件 id = { id }");
    var file = await _dbCtx.FileDatas.Where(f => f.Id == id).FirstOrDefaultAsync();
    if (file != null) 
    {
      var fileFullName = Path.Combine(_webHostEnvironment.ContentRootPath, UPLOADS, file.FileFullSha256[..2], $"{ file.FileFullSha256[2..] }{ file.FileExt }");
      string contentType = MimeTypesMap.GetMimeType(file.FileExt);
      var memory = new MemoryStream();
      using FileStream stream = System.IO.File.OpenRead(fileFullName);
      await stream.CopyToAsync(memory);
      memory.Position = 0;

      // return Ok();
      return File(memory, contentType, file.OriginFileName);
    }
    return NotFound();
  }


  [HttpPost("Callback")]
  public async Task<IActionResult> CallBackAsync(JsonObject json) {
    System.Console.WriteLine("OnlyOffice 触发回调: {0}", json);

    // WebRequest
    var status = json["status"];
    if(status != null && status.GetValue<int>() == 6) {
      var filePath = Path.Combine(_webHostEnvironment.ContentRootPath, "test.xlsx");
      var client = new HttpClient();
      var stream = await client.GetStreamAsync(json["url"]?.ToString());
      using var fs = new FileStream(filePath, FileMode.Create);
      stream.CopyTo(fs);

      // var req = WebRequest.Create((string) json["url"]);
      // var filePath = Path.Combine(_webHostEnvironment.ContentRootPath, "test.xlsx");
      // using (var stream = req.GetResponse().GetResponseStream())
      // using (var fs = System.IO.File.Open(filePath, FileMode.Create))
      // {
      //     var buffer = new byte[4096];
      //     int readed;
      //     while ((readed = stream.Read(buffer, 0, 4096)) != 0)
      //         fs.Write(buffer, 0, readed);
      // }
    }
    return Ok(new {
      Error = 0
    });
  }
}